from pyecharts import options as opts
from pyecharts.charts import Bar, Pie, Line, Scatter, Radar
from pyecharts.globals import ThemeType
from typing import List, Dict, Any


class ChartUtils:
    """
    图表工具类，封装pyecharts常用图表的生成方法
    """

    @staticmethod
    def create_bar_chart(
        title: str,
        x_axis: List[str],
        y_axis: List[Dict[str, Any]],
        x_name: str = "",
        y_name: str = "",
        theme: ThemeType = ThemeType.WHITE,
    ) -> Bar:
        """
        创建条形图

        Args:
            title: 图表标题
            x_axis: X轴数据
            y_axis: Y轴数据，格式为[{"name": "系列名称", "data": [数值列表]}]
            x_name: X轴名称
            y_name: Y轴名称
            theme: 图表主题

        Returns:
            Bar: 条形图对象
        """
        bar = Bar(init_opts=opts.InitOpts(theme=theme))
        bar.set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="shadow"),
            legend_opts=opts.LegendOpts(),
        )
        bar.add_xaxis(x_axis)
        for series in y_axis:
            bar.add_yaxis(series["name"], series["data"])
        return bar

    @staticmethod
    def create_pie_chart(
        title: str, data: List[Dict[str, Any]], radius: str = "55%", theme: ThemeType = ThemeType.WHITE
    ) -> Pie:
        """
        创建饼图

        Args:
            title: 图表标题
            data: 饼图数据，格式为[{"name": "类别名称", "value": 数值}]
            radius: 饼图半径
            theme: 图表主题

        Returns:
            Pie: 饼图对象
        """
        pie = Pie(init_opts=opts.InitOpts(theme=theme))
        pie.set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            legend_opts=opts.LegendOpts(orient="vertical", pos_right="10%", pos_top="center"),
        )
        pie.add(series_name="", data_pair=data, radius=radius, label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
        return pie

    @staticmethod
    def create_line_chart(
        title: str,
        x_axis: List[str],
        y_axis: List[Dict[str, Any]],
        x_name: str = "",
        y_name: str = "",
        is_smooth: bool = False,
        theme: ThemeType = ThemeType.WHITE,
    ) -> Line:
        """
        创建折线图

        Args:
            title: 图表标题
            x_axis: X轴数据
            y_axis: Y轴数据，格式为[{"name": "系列名称", "data": [数值列表]}]
            x_name: X轴名称
            y_name: Y轴名称
            is_smooth: 是否平滑曲线
            theme: 图表主题

        Returns:
            Line: 折线图对象
        """
        line = Line(init_opts=opts.InitOpts(theme=theme))
        line.set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            tooltip_opts=opts.TooltipOpts(trigger="axis"),
            legend_opts=opts.LegendOpts(),
        )
        line.add_xaxis(x_axis)
        for series in y_axis:
            line.add_yaxis(series["name"], series["data"], is_smooth=is_smooth, symbol_size=8)
        return line

    @staticmethod
    def create_scatter_chart(
        title: str,
        x_axis: List[float],
        y_axis: List[Dict[str, Any]],
        x_name: str = "",
        y_name: str = "",
        theme: ThemeType = ThemeType.WHITE,
    ) -> Scatter:
        """
        创建散点图

        Args:
            title: 图表标题
            x_axis: X轴数据
            y_axis: Y轴数据，格式为[{"name": "系列名称", "data": [[x1, y1], [x2, y2], ...]}]
            x_name: X轴名称
            y_name: Y轴名称
            theme: 图表主题

        Returns:
            Scatter: 散点图对象
        """
        scatter = Scatter(init_opts=opts.InitOpts(theme=theme))
        scatter.set_global_opts(
            title_opts=opts.TitleOpts(title=title),
            tooltip_opts=opts.TooltipOpts(trigger="item"),
            legend_opts=opts.LegendOpts(),
        )
        for series in y_axis:
            scatter.add_xaxis(x_axis)
            scatter.add_yaxis(series["name"], series["data"])
        return scatter

    @staticmethod
    def create_radar_chart(
        title: str, indicator: List[Dict[str, Any]], data: List[Dict[str, Any]], theme: ThemeType = ThemeType.WHITE
    ) -> Radar:
        """
        创建雷达图

        Args:
            title: 图表标题
            indicator: 指示器数据，格式为[{"name": "指标名称", "max": 最大值}]
            data: 雷达图数据，格式为[{"name": "系列名称", "data": [数值列表]}]
            theme: 图表主题

        Returns:
            Radar: 雷达图对象
        """
        radar = Radar(init_opts=opts.InitOpts(theme=theme))
        radar.set_global_opts(title_opts=opts.TitleOpts(title=title), legend_opts=opts.LegendOpts())
        for series in data:
            radar.add(series["name"], series["data"])
        return radar

    @staticmethod
    def chart_to_html(chart: Any, file_path: str) -> None:
        """
        将图表保存为HTML文件

        Args:
            chart: 图表对象
            file_path: 保存路径
        """
        chart.render(file_path)

    @staticmethod
    def chart_to_json(chart: Any) -> str:
        """
        将图表转换为JSON字符串

        Args:
            chart: 图表对象

        Returns:
            str: JSON字符串
        """
        return chart.dump_options_with_quotes()
